package com.sirun.ble.utils;

import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.util.Log;

import com.sirun.ble.constants.BleConfig;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author : hzw
 */
public class AwLogFileUtil {

    private static final String TAG = "AwLogFile";

    private static AwLogFileUtil instance;
    private static Context mContext;
    public static final int SIZETYPE_B = 1;
    public static final int SIZETYPE_KB = 2;
    public static final int SIZETYPE_MB = 3;
    public static final int SIZETYPE_GB = 4;
    private static String filePath_log = "";
    private static String mFilePrefix = "_aw";
    private static double mMaxFileSize = 5;
    private static boolean mIsDebug = false;

    public static AwLogFileUtil getInstance() {
        if(instance == null) {
            return new AwLogFileUtil();
        }
        return instance;
    }

    public AwLogFileUtil setDebug(boolean isDebug) {
        mIsDebug = isDebug;
        return this;
    }

    public AwLogFileUtil setFilePrefix(String filePreFix) {
        mFilePrefix = filePreFix;
        return this;
    }

    private void showLog(String str) {
        if(!mIsDebug) {
            return;
        }
        Log.d(TAG, str);
    }

    private static String getLocalFilePath() {
        if (Environment.getExternalStorageState().equals("mounted")) {
            return Environment.getExternalStorageDirectory().toString();
        } else {
            return Environment.getDownloadCacheDirectory().toString();
        }
    }

    public AwLogFileUtil setContext(Context context) {
        mContext = context;
        filePath_log = getFileUrl();
        return this;
    }

    public AwLogFileUtil setMaxFileSize(double fileSize) {
        mMaxFileSize = fileSize;
        return this;
    }

    private List<String> getAllFileList() {
        String dateStr = AwDateUtil.formatDate(AwDateUtil.getSpecDate(System.currentTimeMillis(), Calendar.DAY_OF_YEAR, -3), AwDateUtil.FORMAT_YMD);
        List<String> list = new ArrayList<>();
        File file = new File(mContext.getExternalFilesDir("").getAbsolutePath());
        File files[] = file.listFiles();
        for (int i = 0; i < files.length; i++) { // 遍历目录下所有的文件
            if(files[i].getName().contains(mFilePrefix)) {
                showLog("DelPreDaysRecord Local record file: " + files[i].getName());
                writeFile("DelPreDaysRecord Local record file: " + files[i].getName());
                if(AwDataUtil.getIntValue(files[i].getName().split("_")[0]) <= AwDataUtil.getIntValue(dateStr)) {
                    list.add(files[i].getAbsolutePath());
                }
            }
        }
//        createTestRecordFile();
        return list;
    }

    public AwLogFileUtil delPreDaysRecord() {
        List<String> list = getAllFileList();
        if(!AwDataUtil.isEmpty(list)) {
            for(String temp : list) {
                File file = new File(temp);
                deleteFile(file);
                showLog("DelPreDaysRecord records...file: " + file.getName());
                writeFile("DelPreDaysRecord records...file: " + file.getName());
            }
        } else {
            showLog("DelPreDaysRecord records...empty");
            writeFile("DelPreDaysRecord records...empty");
        }
        return this;
    }

    private void createTestRecordFile() {
        for(int i=-10; i<-6; i++) {
            String dateStr = AwDateUtil.formatDate(AwDateUtil.getSpecDate(System.currentTimeMillis(), Calendar.DAY_OF_YEAR, i), AwDateUtil.FORMAT_YMD) + mFilePrefix + ".txt";
            createFile(mContext.getExternalFilesDir("").getAbsolutePath() + "/" + dateStr);
        }
    }

    private void createFile(String filepath) {
        try {
            File f = new File(filepath);
            if (!f.exists()) {
                f.createNewFile();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private String getFileUrl() {
        String dateStr = AwDateUtil.formatDate(new Date(System.currentTimeMillis()), AwDateUtil.FORMAT_YMD);
        return mContext.getExternalFilesDir("").getAbsolutePath() + "/" + dateStr + mFilePrefix + ".txt";
    }

    public String getDefaultInfoStr() {
        return "当前SDK版本:" + BleConfig.version + ";当前用户设备信息:手机型号" + AwSystemUtil.getSystemModel() + ";Android系统版本:" + Build.VERSION.SDK_INT;
    }

    public void writeDefault(boolean isMain) {
        if(isMain) {
            writeFile("Main." + getDefaultInfoStr());
        } else {
            writeFile(getDefaultInfoStr());
        }
    }

    public void writeFile(String str) {
        if(AwDataUtil.isEmpty(filePath_log)) {
            showLog("writeFile isEmpty filePath_log");
            return;
        }
        FileWriter writer = null;
        try {
            File f = new File(filePath_log);
            if (!f.exists()) {
                f.createNewFile();
                writeDefault(false);
            }
            double fileSize = getFileOrFilesSize(filePath_log, SIZETYPE_MB);
            showLog("writeFile fileSize: " + fileSize);
            if(fileSize > mMaxFileSize) {
                showLog("fileSize > mMaxFileSize to delete...");
                f.delete();
                f.createNewFile();
                writeFile("Exceeding the size..." + mMaxFileSize + " MB,delete old data, create new file");
                writeDefault(false);
            }
            showLog("writeFile str: " + str);
            String dateStr = AwDateUtil.formatDate(new Date(System.currentTimeMillis()), "HH:mm:ss");
            writer = new FileWriter(f, true);
            writer.write("【" + dateStr + "】 " + str + "\n");
            writer.flush();
        } catch (Exception e) {
            e.printStackTrace();
            showLog("writeFile Exception: " + e.getMessage());
        } finally {
            try {
                writer.close();
            } catch (Exception e) {
                e.printStackTrace();
                showLog("writeFile close Exception: " + e.getMessage());
            }
        }
    }

    private double getFileOrFilesSize(String filePath, int sizeType) {
        File file = new File(filePath);
        long blockSize = 0;
        try {
            if (file.isDirectory()) {
                blockSize = getFileSizes(file);
            } else {
                blockSize = getFileSize(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
            showLog("获取文件大小失败!");
        }
        return FormetFileSize(blockSize, sizeType);
    }

    /**
     * 获取指定文件大小
     *
     * @throws Exception
     */
    private long getFileSize(File file) throws Exception {
        long size = 0;
        if (file.exists()) {
            FileInputStream fis = new FileInputStream(file);
            size = fis.available();
        } else {
            file.createNewFile();
            showLog("获取文件大小, 文件不存在!");
        }
        return size;
    }


    /**
     * 获取下载 URL 的文件的大小
     */
    private long getFileSize(String address) {
        long filesize = 0;
        HttpURLConnection urlConn = null;
        try {
            URL url = new URL(address);
            urlConn = (HttpURLConnection) url.openConnection();
            urlConn.setConnectTimeout(10000);
            urlConn.setReadTimeout(10000);
            urlConn.connect();
            filesize = urlConn.getContentLength();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            urlConn.disconnect();
        }
        return filesize;
    }

    /**
     * 获取指定文件夹(目录)大小
     *
     * @param f
     * @return
     * @throws Exception
     */
    private long getFileSizes(File f) throws Exception {
        long size = 0;
        File flist[] = f.listFiles();
        for (int i = 0; i < flist.length; i++) {
            if (flist[i].isDirectory()) {
                size = size + getFileSizes(flist[i]);
            } else {
                size = size + getFileSize(flist[i]);
            }
        }
        return size;
    }

    /**
     * 转换文件大小
     *
     * @param fileS
     * @return
     */
    private String FormetFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return fileSizeString;
    }

    /**
     * 转换文件大小,指定转换的类型
     *
     * @param fileS
     * @param sizeType
     * @return
     */
    private double FormetFileSize(long fileS, int sizeType) {
        DecimalFormat df = new DecimalFormat("#.00");
        double fileSizeLong = 0;
        switch (sizeType) {
            case SIZETYPE_B:
                fileSizeLong = Double.valueOf(df.format((double) fileS));
                break;
            case SIZETYPE_KB:
                fileSizeLong = Double.valueOf(df.format((double) fileS / 1024));
                break;
            case SIZETYPE_MB:
                fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576));
                break;
            case SIZETYPE_GB:
                fileSizeLong = Double.valueOf(df
                        .format((double) fileS / 1073741824));
                break;
            default:
                break;
        }
        return fileSizeLong;
    }

    /**
     * 删除文件(不包含目录)
     *
     * @param file
     */
    private void deleteFile(File file) {
        if (file.exists()) { // 判断文件是否存在
            if (file.isFile()) { // 判断是否是文件
                file.delete(); // delete()方法 你应该知道 是删除的意思;
            } else if (file.isDirectory()) { // 否则如果它是一个目录
                File files[] = file.listFiles(); // 声明目录下所有的文件 files[];
                for (int i = 0; i < files.length; i++) { // 遍历目录下所有的文件
                    deleteFile(files[i]); // 把每个文件 用这个方法进行迭代
                }
            }
            // file.delete();
        } else {
            // SystemInfo.showToast(GrrzXrzAct.this, "文件不存在!");
        }
    }

}
